/*
 * Package il.ac.biu.cs.grossmm.test.cppToFooAdapter
 * File Client.java
 * 
 * This is a part of presence service framework API. 
 * See javadoc for more information.
 *  
 * Copyright (C) 2006 Grossmann Mark
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package il.ac.biu.cs.grossmm.tests.fooClients;

import il.ac.biu.cs.grossmm.foo.format.*;
import il.ac.biu.cs.grossmm.foo.format.PresenceDoc.Tuple;
import il.ac.biu.cs.grossmm.foo.protocol.*;
import il.ac.biu.cs.grossmm.tests.fooAdapters.Server;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Client extends SingleClient {

	private static final String rulesDocType = "foo.WatcherRulesDoc";
	private static final String presenceDocType = "foo.PresenceDoc";

	@Override
	protected Response requestReceived(Request request)
	{
		System.out.println("<=== "+request);
		
		if (!(request instanceof NotifyRequest)) {
			System.out.println("Not a notification");
			System.out.println("---> "+ResponseCodes.BAD_REQUEST);
			return new Response(request, ResponseCodes.BAD_REQUEST);
		}
		NotifyRequest nr = (NotifyRequest) request;

	
		System.out.println("---> 200 ("+request.getCommand()+")");

		return request.okResponse();
	}

	void send(Request request) throws IOException, InterruptedException
	{
		Thread.sleep(1000);
		
		System.out.println("===> " + request);

		Response response = sendRequest(request);

		System.out.println("<--- " + response + "("+request.getCommand()+")\n");

	}

	public static void main(String[] args) throws UnknownHostException,
		IOException, InterruptedException
	{
		Logger logger = Logger.getLogger("");
		Handler[] hh = logger.getHandlers();
		for (Handler h : hh)
			h.setLevel(Level.OFF);

		new Thread() {
			public void run()
			{
				try {
					Server.main(null);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();

		Thread.sleep(5000);

		Client client = new Client();

		client.connectTo("localhost", 4004);

		System.out.println("Connected.");

		Response resp;

		client.send(new HelloRequest("Bob", "boob"));
		client.send(new HelloRequest("Alice", "al11z"));
		
		
// 		sendPresence1(client);

		
// 	    PUBLISH PRIVACY POLICY: ALLOW ALL
		
		WatcherRulesDoc rdoc = new WatcherRulesDoc();
		rdoc.addPersonalRules(null, null, true);
		rdoc.addServiceRules(null, null, null, true, true, false);

		client.send(new PublishRequest("0", "Alice", 900,
			rulesDocType, rdoc.serialize()));
		Thread.sleep(2000);
		
		
		
//		PUBLISH PRESENCE ver 1
		
		sendPresence1(client);
		Thread.sleep(2000);

		
//		SUBSCRIBE
		
		client.send(new SubscribeRequest("Alice", "Alice", 60));
		Thread.sleep(2000);

	
//		PUBLISH PRESENCE ver 2
		sendPresence2(client);
		Thread.sleep(2000);
		
		

//		rdoc = new WatcherRulesDoc();
//		rdoc.addPersonalRules(null, null, true, false, true, false);
//		
//		client.send(new PublishRequest("0", "Alice", 1800,
//			rulesDocType, rdoc.serialize()));
//		Thread.sleep(2000);
		
//		rdoc = new WatcherRulesDoc();
//		rdoc.addPersonalRules(null, null, true);
//		
//		client.send(new PublishRequest("0", "Alice", 1800,
//				rulesDocType, rdoc.serialize()));
//		Thread.sleep(2000);
		
//		PUBLISH PRESENCE ver 3
		sendPresence3(client);

		Thread.sleep(50000);

		client.disconnect();
	}

	/**
	 * @param client
	 * @throws IOException
	 * @throws InterruptedException
	 */
	private static void sendPresence1(Client client) throws IOException,
		InterruptedException
	{
		Tuple t2 =
			new Tuple("124", .1f, "me@kitchen.home.com", OnlineStatus.OFFLINE,
				"personal", Capabilities.of("voice"));

		Tuple t3 =
			new Tuple("129", .8f, "me@kitchen.home.com", OnlineStatus.ONLINE,
				"personal", Capabilities.of("video"));

		PresenceDoc foo =
			new PresenceDoc("Alice", new Mood(1, 8, 3, 6), new Activities(Activity.MEAL,
				Activity.HOLIDAY), "kitchen", "home", t2, t3);

		client.send(new PublishRequest("1", "Alice", 1800, presenceDocType,
			foo.serialize()));

	}

	private static void sendPresence2(Client client) throws IOException,
		InterruptedException
	{
		Tuple t2 =
			new Tuple("124", .1f, "me@kitchen.home.com", OnlineStatus.OFFLINE,
				"personal", Capabilities.of("voice"));

		Tuple t3 =
			new Tuple("129", .8f, "me@kitchen.home.com", OnlineStatus.ONLINE,
				"personal", Capabilities.of("video"));

		PresenceDoc foo =
			new PresenceDoc("Alice",  new Mood(1, 8, 3, 6), new Activities(Activity.MEAL,
				Activity.HOLIDAY), "kitchen", "home", t2, t3);

		foo.setSphere("athmoSphere");

		client.send(new PublishRequest("1", "Alice", 1800, presenceDocType,
			foo.serialize()));

		foo.removeTuple("129");

		client.send(new PublishRequest("1", "Alice", 1800, presenceDocType,
			foo.serialize()));

		PresenceDoc foo2 =
			new PresenceDoc("Alice",  new Mood(0, 0, 8, 8), new Activities(
				Activity.ON_THE_PHONE), null, "home");

		client.send(new PublishRequest("2", "Alice", 1800, presenceDocType,
			foo2.serialize()));
	}
	
	private static void sendPresence3(Client client) throws IOException,
	InterruptedException
{
	PresenceDoc foo2 =
		new PresenceDoc("Alice",  new Mood(0, 0, 8, 8), new Activities(
			Activity.APPOINTMENT), null, "home");

	client.send(new PublishRequest("2", "Alice", 1800, presenceDocType,
		foo2.serialize()));
}
}
